package com.cz.ssyx.acl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cz.ssyx.acl.mapper.PermissionMapper;
import com.cz.ssyx.acl.service.PermissionService;
import com.cz.ssyx.acl.service.RolePermissionService;
import com.cz.ssyx.acl.utils.PermissionHelper;
import com.cz.ssyx.model.acl.Permission;
import com.cz.ssyx.model.acl.RolePermission;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @descriptions:
 * @author: Joker.
 * @date: 2024/4/16 18:26
 * @version: 1.0
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Autowired
    private RolePermissionService rolePermissionService;

    //获取全部菜单信息和该角色的菜单信息
    @Override
    public Map<String, Object> getRolePermission(Long roleId) {

        //获取所有菜单集合
        List<Permission> allPermission = this.list();
//        for (Permission permission : allPermission) {
//            permission.setSelect(true);
//        }

        //存储该角色下的菜单集合
        List<Permission> rolePermission = new ArrayList<>();

        //获取该角色下的所有菜单
        LambdaQueryWrapper<RolePermission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RolePermission::getRoleId, roleId);
        List<RolePermission> role_Permission = rolePermissionService.list(queryWrapper);

        //遍历role_Permission
        // 得到该角色下的所有菜单的id
        List<Long> permissionIds = role_Permission.stream()
                                    .map(item -> item.getPermissionId()).collect(Collectors.toList());

        //遍历全部的菜单集合
        for (Permission permission : allPermission) {
            //如果包含该角色下某个菜单的id
            if (permissionIds.contains(permission.getId())){
                permission.setSelect(true);
                //添加到该角色的菜单集合
                rolePermission.add(permission);
            }
        }

        Map<String, Object> map = new HashMap<>();

        map.put("assignPermission", PermissionHelper.buildPermission(rolePermission));
        map.put("allPermissions", PermissionHelper.buildPermission(allPermission));

        return map;
    }

    //获取权限(菜单/功能)列表
    @Override
    public List<Permission> queryAllPermission() {
        //1.先查出所有的菜单
        List<Permission> allPermissions = this.list();

        //2.编写一个工具类，转换菜单数据格式
        List<Permission> result = PermissionHelper.buildPermission(allPermissions);

        return result;
    }

    //递归删除菜单
    @Override
    public void removeChildById(Long id) {

        //创建一个要删除菜单id的集合
        List<Long> permissionIds = new ArrayList<>();

        //先加入该菜单id
        permissionIds.add(id);

        //递归查找该菜单下是否有子菜单
        getAllPermissionId(id, permissionIds);

        //删除所有菜单
        this.removeByIds(permissionIds);
    }

    //为角色分配权限
    @Override
    public void doRolePermission(Long roleId, List<Long> permissionId) {
        //1.先清空该角色下的所有菜单
        LambdaQueryWrapper<RolePermission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RolePermission::getRoleId, roleId);
        rolePermissionService.remove(queryWrapper);

        //2.再为该角色赋值菜单
        //2.1构建一个角色菜单关系对象
        List<RolePermission> rolePermissionList = permissionId.stream().map(item ->{
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(item);
            return rolePermission;
        }).collect(Collectors.toList());
        //2.2保存到数据库
        rolePermissionService.saveBatch(rolePermissionList);
    }

    /**
     * 定义一个递归删除菜单以及子菜单的函数
     * @param id
     * @param permissionIds
     */
    private void getAllPermissionId(Long id, List<Long> permissionIds) {

        //查出该菜单下所有的子菜单
        LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Permission::getPid, id);
        List<Permission> childPermissions = this.list(queryWrapper);

        //遍历查出来的子菜单集合
        childPermissions.stream().forEach(item -> {
            //把遍历出的子菜单加入到要删除的菜单id集合
            permissionIds.add(item.getId());

            //递归
            this.getAllPermissionId(item.getId(), permissionIds);
        });
    }
}
